home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CommToolbox (modified) / Sources / CScrollBuffer.cp < prev    next >
Encoding:
Text File  |  1994-11-30  |  13.1 KB  |  516 lines  |  [TEXT/KAHL]

  1. **********************/
  2.  
  3. void    CScrollBuffer::IScrollBuffer(long maxNumLines)
  4. {
  5.     inherited::IAbstractBuffer();
  6.  
  7.     /* Initialize instance variables */
  8.     
  9.     maxLines = maxNumLines;
  10.     
  11.     itsTextHandle = NewHandle(0);
  12.     
  13.     Truncate();
  14.     
  15.     /*itsLineStarts = (LongHandle) NewHandle(sizeof(long));
  16.     **itsLineStarts = 0;*/
  17. }
  18.  
  19. /******************************************************************************
  20.  
  21.  
  22. ******************************************************************************/
  23.  
  24. void    CScrollBuffer::Dispose(void)
  25. {
  26.     ForgetHandle(itsTextHandle);
  27.     //ForgetHandle(itsLineStarts);
  28.     inherited::Dispose();
  29. }
  30.  
  31. /** Text Specification **/
  32.  
  33. void    CScrollBuffer::SetTextPtr(Ptr textPtr, long numChars)
  34. {
  35. }
  36.  
  37. void    CScrollBuffer::UseTextHandle(Handle textHandle)
  38. {
  39. }
  40.  
  41. /******************************************************************************
  42.  InsertTextPtr
  43.  
  44.  add text to the buffer.
  45. ******************************************************************************/
  46.  
  47. void    CScrollBuffer::InsertTextPtr(Ptr insertPtr, long insertLen)
  48. {
  49.  if (itsNumLines < maxLines)
  50.  {
  51.     Ptr        textP;
  52.      long    oldTextLen = itsActualLength;
  53.      
  54.       if (EnlargeBuffer(insertLen + 1))
  55.       {
  56.         textP = *itsTextHandle;
  57.         textP[oldTextLen] = (char)insertLen;
  58.         BlockMove(insertPtr, textP + oldTextLen + 1, insertLen);
  59.         
  60.         itsTextLength += insertLen;
  61.         itsActualLength += insertLen + 1;
  62.     }
  63.  }
  64. }
  65.  
  66. /******************************************************************************
  67. CopyTextRange - copy desired section of buffer as (possibly) multi-
  68.                 lined formatted text.
  69.  
  70. ******************************************************************************/
  71.  
  72. Handle    CScrollBuffer::CopyTextRange(long start, long end)
  73. {
  74.     register long        lineNum, lineLen, beginLine, endLine, lineOffset;
  75.     register long        physLineBegin = 0L, physCharOffset = 0L;
  76.     register long        endPhysCharOffset = 0L, endPhysLineBegin = 0L;
  77.     register Handle        hTextCopy = NULL;
  78.     register long        textOffset = 0L;
  79.     register StringPtr    textP = (unsigned char *)*itsTextHandle;
  80.     
  81.     //    sanity check
  82.     start = Max(start, 0);
  83.     end = Min(end, GetTextLength() - 1);
  84.     
  85.     //    allocate buffer to size of text, it's at least as large as we need.
  86.     hTextCopy = NewHandleCanFail(GetHandleSize(itsTextHandle) + 1);
  87.     FailMemError();
  88.     
  89.     StringPtr    copyTextPtr = (unsigned char *)*hTextCopy;
  90.     
  91.     //    find offset of first and last character    
  92.     GetCharInfo(end, &endLine, &endPhysLineBegin, &endPhysCharOffset);
  93.     GetCharInfo(start, &beginLine, &physLineBegin, &physCharOffset);
  94.     
  95.     lineLen = (long)textP[physLineBegin - 1];
  96.     
  97.     /*
  98.         while the current line does not contain the last character, copy
  99.         the line to buffer and trim trailing white space, add line feed. Apply
  100.         to all lines.
  101.     */
  102.         
  103.     for (lineNum = beginLine; lineNum <= endLine; lineNum++)
  104.     {
  105.         register long    copyLen = lineLen;
  106.         
  107.         // if first line, start at offset of first character
  108.         if (lineNum == beginLine)
  109.             lineOffset = physCharOffset - physLineBegin;
  110.         else
  111.             lineOffset = 0L;
  112.         
  113.         // if last line, only include characters up to and including last character
  114.         if (lineNum == endLine)
  115.             copyLen = (endPhysCharOffset - endPhysLineBegin) + 1;
  116.             
  117.         // calculate number of characters to copy.
  118.         copyLen -= lineOffset;
  119.             
  120.         BlockMove(textP + physLineBegin + lineOffset, copyTextPtr + textOffset, copyLen);
  121.         copyTextPtr[textOffset + copyLen] = '\0';
  122.         textOffset = strlen(strcat(TrimRight((char *)copyTextPtr),"\r"));
  123.         
  124.         lineLen = (long)textP[lineLen + 1];            // get next line length
  125.         physLineBegin += lineLen + sizeof(char);    // point to beginning of next line.
  126.     }
  127.         
  128.     // shrink handle to actual size, and return it.
  129.     SetHandleSize(hTextCopy, textOffset);
  130.     
  131.     return hTextCopy;
  132. }
  133.  
  134. void    CScrollBuffer::ReplaceSelection(Ptr replacePtr, long replaceLen)
  135. {
  136. }
  137.  
  138. /** Accessing **/
  139. Handle    CScrollBuffer::GetTextHandle(void)
  140. {
  141.     return itsTextHandle;
  142. }
  143.  
  144. Handle    CScrollBuffer::GetRawTextHandle(void)
  145. {
  146.     return itsTextHandle;
  147. }
  148.     
  149. /******************************************************************************
  150. FindLine
  151.  
  152.     find line that given character belongs to.
  153.  
  154. ******************************************************************************/
  155.  
  156. long    CScrollBuffer::FindLine(long charPos)
  157. {
  158.     long lineNum, physLineBegin, physCharOffset;
  159.     
  160.     GetCharInfo(charPos, &lineNum, &physLineBegin, &physCharOffset);
  161.     
  162.     return Min(lineNum,itsNumLines - 1);
  163. }
  164.  
  165. /******************************************************************************
  166. GetLineStart
  167.  
  168. ******************************************************************************/
  169.  
  170. long    CScrollBuffer::GetLineStart(long line)
  171. {
  172.     long    lineOffset = 0L, lineLen = 0L, logOffset = 0L;
  173.     
  174.     GetLineInfoX (line, &lineOffset, &logOffset, &lineLen);
  175.  
  176.     return logOffset;
  177. }
  178.  
  179. /******************************************************************************
  180. GetLineEnd
  181.  
  182. ******************************************************************************/
  183.  
  184. long    CScrollBuffer::GetLineEnd(long line)
  185. {
  186.     long    lineOffset = 0L, lineLen = 0L, logOffset = 0L;
  187.     
  188.     GetLineInfoX (line, &lineOffset, &logOffset, &lineLen);
  189.  
  190.     return logOffset + lineLen - 1;
  191. }
  192.  
  193. /******************************************************************************
  194. GetLineLength
  195.  
  196. ******************************************************************************/
  197.  
  198. short    CScrollBuffer::GetLineLength(long line)
  199. {
  200.     long    lineOffset = 0L, lineLen = 0L, logOffset = 0L;
  201.     
  202.     GetLineInfoX (line, &lineOffset, &logOffset, &lineLen);
  203.  
  204.     return lineLen;
  205. }
  206.  
  207. /******************************************************************************
  208. GetLength
  209.  
  210. ******************************************************************************/
  211.  
  212. long    CScrollBuffer::GetLength(void)
  213. {
  214.     long    lineOffset = 0L, lineLen = 0L, logOffset = 0L;
  215.     
  216.     GetLineInfoX (itsNumLines - 1, &lineOffset, &logOffset, &lineLen);
  217.  
  218.     return lineOffset + lineLen;
  219. }
  220.  
  221. /******************************************************************************
  222. GetNumLines
  223.  
  224. ******************************************************************************/
  225.  
  226. long    CScrollBuffer::GetNumLines(void)
  227. {
  228.     return itsNumLines;
  229. }
  230.  
  231. void    CScrollBuffer::GetSelection(long *selStart, long *selEnd)
  232. {
  233. }
  234.  
  235. void    CScrollBuffer::GetCharAt(long *aPosition, tCharBuf charBuf)
  236. {
  237.     if ((itsTextLength > 0) && (*aPosition < itsTextLength))
  238.     {    
  239.         long        lineNum, physLineBegin, physCharOffset;
  240.         StringPtr    textP = (unsigned char *)*itsTextHandle;
  241.     
  242.         GetCharInfo(*aPosition, &lineNum, &physLineBegin, &physCharOffset);
  243.         
  244.         Length(charBuf) = 1;
  245.         charBuf[1] = textP[physCharOffset];
  246.         
  247.     }
  248.     else Length(charBuf) = 0;
  249. }
  250.  
  251. void    CScrollBuffer::GetCharBefore(long *aPosition, tCharBuf charBuf)
  252. {
  253.     if ((itsTextLength > 0) && (*aPosition <= itsTextLength))
  254.     {
  255.         (*aPosition)--;
  256.         GetCharAt(aPosition, charBuf);
  257.     }
  258. }
  259.  
  260. void    CScrollBuffer::GetCharAfter(long *aPosition, tCharBuf charBuf)
  261. {
  262.     if ((itsTextLength > 0) && (*aPosition < itsTextLength - 1))
  263.     {
  264.         (*aPosition)++;
  265.         GetCharAt(aPosition, charBuf);
  266.     }
  267. }
  268.  
  269. long    CScrollBuffer::GetGapPosition(void)
  270. {
  271.     return 0L;
  272. }
  273.  
  274. long    CScrollBuffer::GetGapLength(void)
  275. {
  276.     return 0L;
  277. }
  278.  
  279. /******************************************************************************
  280.  EnlargeBuffer
  281.  
  282.  like the sign says: make it bigger.
  283. ******************************************************************************/
  284.  
  285. void    CScrollBuffer::ReplaceLine(Ptr replacePtr, long replaceLen, long line)
  286. {
  287. }
  288.  
  289. /******************************************************************************
  290.  AddLine
  291.  
  292.  add a new line.
  293. ******************************************************************************/
  294.  
  295. void    CScrollBuffer::AddLine(Ptr newLinePtr, long newLineLen)
  296. {
  297.     InsertTextPtr(newLinePtr, newLineLen);
  298.     itsNumLines++;
  299. }
  300.  
  301. /******************************************************************************
  302.  DeleteLine
  303.  
  304.  delete line from buffer.
  305. ******************************************************************************/
  306.  
  307. void    CScrollBuffer::DeleteLine(long line)
  308. {
  309.     long        lineOffset = 0L, lineLen = 0L, logOffset = 0L, remainderLen;
  310.     StringPtr    textP = (unsigned char *)*itsTextHandle;
  311.     
  312.     GetLineInfoX (line, &lineOffset, &logOffset, &lineLen);
  313.     remainderLen = GetActualBufferLength(line,-1);
  314.         
  315.     BlockMove(textP + lineOffset + lineLen,
  316.               textP + lineOffset - sizeof(char),
  317.               remainderLen);
  318.  
  319.     itsTextLength -= lineLen;
  320.     itsActualLength -= lineLen + 1;
  321.     
  322.     itsNumLines--;
  323. }
  324.  
  325. /******************************************************************************
  326.  GetLine
  327.  
  328.  get a line as a C string.
  329. ******************************************************************************/
  330.  
  331. void    CScrollBuffer::GetLine(long line, StringPtr strLine, long maxLen)
  332. {
  333.     long        lineOffset = 0L, lineLen = 0L, logOffset = 0L, remainderLen;
  334.     StringPtr    textP = (unsigned char *)*itsTextHandle;
  335.     
  336.     GetLineInfoX (line, &lineOffset, &logOffset, &lineLen);
  337.     lineLen = Min(lineLen,maxLen-1);
  338.         
  339.     BlockMove(textP + lineOffset,strLine,lineLen);
  340.     strLine[lineLen] = 0;
  341. }
  342.     
  343. /******************************************************************************
  344.  EnlargeBuffer
  345.  
  346.  like the sign says: make it bigger.
  347. ******************************************************************************/
  348.  
  349. Boolean    CScrollBuffer::EnlargeBuffer(long delta)
  350. {
  351.      long    amountNeeded, oldTextLen = GetHandleSize(itsTextHandle);
  352.      Boolean    itWorked = true;
  353.      
  354.      // see how much we really need
  355.      amountNeeded = (itsActualLength + delta) - oldTextLen;
  356.      
  357.      if (amountNeeded > 0)
  358.      {
  359.           TRY
  360.           {
  361.              ResizeHandleCanFail(itsTextHandle, oldTextLen + amountNeeded);
  362.             FailMemError();
  363.         }
  364.         CATCH
  365.         {
  366.             SetHandleSize(itsTextHandle, oldTextLen);
  367.             itWorked = false;
  368.         }
  369.         ENDTRY
  370.     }
  371.     return itWorked;
  372. }
  373.  
  374. /******************************************************************************
  375.  GetLineInfo
  376.  
  377.  get position and length of line.
  378. ******************************************************************************/
  379.  
  380. void    CScrollBuffer::GetLineInfo(long line, long *start, long *len)
  381. {
  382.     long    physical_start;
  383.     
  384.     GetLineInfoX(line, &physical_start, start, len);
  385. }
  386.  
  387. /******************************************************************************
  388.  GetLineInfoX
  389.  
  390.  get position and length of line.
  391. ******************************************************************************/
  392.  
  393. void    CScrollBuffer::GetLineInfoX(long line, long *start, long *log_start, long *len)
  394. {
  395.     StringPtr    textP = (unsigned char *)*itsTextHandle;
  396.     long        lineNum = 0L;
  397.     
  398.     *start = *len = 0L;
  399.     
  400.     while (lineNum < itsNumLines && lineNum <= line)
  401.     {     
  402.      *start += sizeof(char) + *len;
  403.      *log_start += *len;
  404.      
  405.      *len = (long)*(char *)textP;
  406.      textP += sizeof(char) + *len;
  407.      
  408.      lineNum++;
  409.     }
  410.  
  411. }
  412.  
  413. /******************************************************************************
  414.  GetActualBufferLength
  415.  
  416.  get length of all or part of the actual buffer.
  417. ******************************************************************************/
  418.  
  419. long    CScrollBuffer::GetActualBufferLength(long startLine, long endLine)
  420. {
  421.     StringPtr    textP = (unsigned char *)*itsTextHandle;
  422.     long        lineNum, bufLen = 0L;
  423.     
  424.     if (startLine < 0)
  425.         startLine = 0;
  426.     
  427.     if (endLine < 0)
  428.         endLine = itsNumLines - 1;
  429.         
  430.     for (lineNum = 0L; lineNum < itsNumLines && lineNum <= endLine; lineNum++)
  431.     {     
  432.      long len = sizeof(char) + (long)*(char *)textP;
  433.      
  434.      if (lineNum >= startLine)
  435.          bufLen += len;
  436.          
  437.      textP += len;
  438.     }
  439.     
  440.     return bufLen;
  441. }
  442.  
  443. /******************************************************************************
  444.  GetMaxLines
  445.  
  446.  get max number of lines.
  447. ******************************************************************************/
  448.  
  449. long    CScrollBuffer::GetMaxLines(void)
  450. {
  451.     return maxLines;
  452. }
  453.  
  454. /******************************************************************************
  455.  GetMaxLines
  456.  
  457.  get max number of lines.
  458. ******************************************************************************/
  459.  
  460. void    CScrollBuffer::Truncate(void)
  461. {
  462.     SetHandleSize(itsTextHandle,0);
  463.     itsTextLength = itsActualLength = 0;
  464.     itsNumLines = 0;
  465. }
  466.  
  467. /******************************************************************************
  468.  GetTextLength
  469.  
  470.  return test length.
  471. ******************************************************************************/
  472.  
  473. long    CScrollBuffer::GetTextLength(void)
  474. {
  475.     return itsTextLength;
  476. }
  477.  
  478. /******************************************************************************
  479.  GetCharInfo
  480.  
  481.  get information about position of physical location of given character.
  482. ******************************************************************************/
  483.  
  484. void    CScrollBuffer::GetCharInfo(long charPos, long *line, long *physLineBegin, long *physCharOffset)
  485. {
  486.     StringPtr    textP, saveTextP;
  487.     long        lineNum, bufLen = 0L;
  488.         
  489.     // sanity check
  490.     charPos = Max(charPos,0);
  491.     charPos = Min(charPos,itsTextLength - 1);
  492.     
  493.     textP = saveTextP = (unsigned char *)*itsTextHandle;
  494.         
  495.     for (lineNum = 0L; lineNum < itsNumLines; lineNum++)
  496.     {     
  497.         long len = (long)*(char *)textP;
  498.           
  499.         textP += sizeof(char);
  500.             
  501.         if (charPos < bufLen + len)
  502.         {        
  503.             *line = lineNum;
  504.             *physLineBegin = (long)(textP - saveTextP);
  505.             *physCharOffset = (long)(&textP[charPos - bufLen] - saveTextP);
  506.             break;
  507.         }
  508.              
  509.         bufLen += len;
  510.         textP += len;
  511.     }
  512. }
  513.  
  514.  
  515.  
  516.